using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using CodePlex.DnD4eCampaignManager.CampaignManagerTests.TestUtilities;
using CodePlex.DnD4eCampaignManager.DnD4e.Interfaces;
using CodePlex.DnD4eCampaignManager.Repositories;
using CodePlex.DnD4eCampaignManager.Repositories.Interfaces;
using NUnit.Framework;

namespace CodePlex.DnD4eCampaignManager.CampaignManagerTests.RepositoryTests
{
    [TestFixture]
    public class MonsterRepositoryTests
    {
        [Test]
        public void IndexedMonstersAreNotPersisted()
        {
            IMonsterRepository monsterRepository = new MonsterRepository();
            IMonster monster = DefaultTestObjects.TestMonster();
            monster.Index = null;
            monsterRepository.Save(monster);
            IMonster monsterFromFile = monsterRepository.GetByName(monster.Name);
            Assert.AreEqual(null, monsterFromFile.Index);
            monsterFromFile.Index = 5;
            monsterFromFile.InitiativeModifier = monster.InitiativeModifier + 10;
            monsterRepository.Save(monsterFromFile);
            monsterFromFile = monsterRepository.GetByName(monsterFromFile.Name);
            Assert.AreEqual(monster.Name, monsterFromFile.Name);
            Assert.AreEqual(monster.InitiativeModifier, monsterFromFile.InitiativeModifier);
        }

        [Test]
        public void MonsterRepositoryCanListAllMonsters()
        {
            IMonsterRepository monsterRepository = new MonsterRepository();
            List<string> namesFromFileSystem = new List<string>();
            foreach ( string monster in Directory.GetFiles("Monsters") )
            {
                string monsterName = monster.Replace("Monsters\\", string.Empty).Replace(".Monster", string.Empty).Replace(".monster", string.Empty);
                if ( monsterName != string.Empty )
                {
                    namesFromFileSystem.Add(monsterName);
                }
            }
            ReadOnlyCollection<string> monstersFromFileSystem = monsterRepository.GetAllNames();
            for ( int i = 0; i < namesFromFileSystem.Count; i++ )
            {
                Console.Out.WriteLine("monstersFromFileSystem [{1}] = {0}", monstersFromFileSystem[i], i);
                Assert.AreEqual(namesFromFileSystem[i], monstersFromFileSystem[i]);
            }
        }

        [Test]
        public void MonsterRepositoryCanSaveMonsterAndGetByName()
        {
            IMonsterRepository monsterRepository = new MonsterRepository();
            IMonster monster = DefaultTestObjects.TestMonster();
            monster.HitPointsMaximum = 50;
            monster.HitPointsCurrent = 40;
            monsterRepository.Save(monster);
            IMonster monsterFromFile = monsterRepository.GetByName(monster.Name);
            Assert.AreEqual(monster.Name, monsterFromFile.Name);
            Assert.AreEqual(monster.MovementSpeedOther, monsterFromFile.MovementSpeedOther);
            Assert.AreEqual(monster.DefenseArmorClass, monsterFromFile.DefenseArmorClass);
            Assert.AreEqual(monster.AttackPowers, monsterFromFile.AttackPowers);
            Assert.AreEqual(monster.Conditions, monsterFromFile.Conditions);
            Assert.AreEqual(monster.HitPointsCurrent, monsterFromFile.HitPointsCurrent);
            Assert.AreEqual(monster.DefenseFortitude, monsterFromFile.DefenseFortitude);
            Assert.AreEqual(monster.HitPointsMaximum, monsterFromFile.HitPointsMaximum);
            Assert.AreEqual(0, monsterFromFile.InitiativeScore);
            Assert.AreEqual(monster.InitiativeModifier, monsterFromFile.InitiativeModifier);
            Assert.AreEqual(monster.Tactics, monsterFromFile.Tactics);
            Assert.AreEqual(monster.DefenseReflex, monsterFromFile.DefenseReflex);
            Assert.AreEqual(monster.MovementSpeed, monsterFromFile.MovementSpeed);
            Assert.AreEqual(monster.HitPointsTemporary, monsterFromFile.HitPointsTemporary);
        }

        [Test]
        public void MonsterRepositoryDoesNotReturnAMonsterWithoutANameWithTheListOfMonsterNames()
        {
            IMonsterRepository monsterRepository = new MonsterRepository();
            List<string> namesFromFileSystem = new List<string>();
            if ( !File.Exists("Monsters\\.Monster") )
            {
                File.WriteAllText("Monsters\\.Monster", "Whatever, this file should never load.");
            }
            foreach ( string monster in Directory.GetFiles("Monsters") )
            {
                string monsterName = monster.Replace("Monsters\\", string.Empty).Replace(".Monster", string.Empty).Replace(".monster", string.Empty);
                namesFromFileSystem.Add(monsterName);
            }
            ReadOnlyCollection<string> monstersFromFileSystem = monsterRepository.GetAllNames();
            Assert.AreEqual(namesFromFileSystem.Count - 1, monstersFromFileSystem.Count);
            for ( int i = 0; i < monstersFromFileSystem.Count; i++ )
            {
                Assert.Contains(monstersFromFileSystem[i], namesFromFileSystem);
            }
            if ( File.Exists("Monsters\\.Monster") )
            {
                File.Delete("Monsters\\.Monster");
            }
        }

        [Test]
        public void MonstersWithNoNameAreNotPersisted()
        {
            IMonsterRepository monsterRepository = new MonsterRepository();
            IMonster monster = DefaultTestObjects.TestMonster();
            monster.Name = string.Empty;
            monsterRepository.Save(monster);
            IMonster monsterFromFile = monsterRepository.GetByName(monster.Name);
            Assert.IsNull(monsterFromFile);
        }
    }
}